From 909c78b153d7688d1d21a2d00193186e1556b2f2 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Mon, 17 Mar 2003 18:25:34 +0000 Subject: [PATCH] bitkeeper revision 1.145 (3e76131eo2ToZ75trWvK5ELYWyDIXQ) pci_ids.h, pci.ids, tg3.h, tg3.c: Brand new exciting tg3 driver. IAP can test this :-) --- xen/drivers/net/tg3.c | 380 ++++++++++++++++++++++++++----------- xen/drivers/net/tg3.h | 9 +- xen/drivers/pci/pci.ids | 31 ++- xen/include/xeno/pci_ids.h | 14 ++ 4 files changed, 313 insertions(+), 121 deletions(-) diff --git a/xen/drivers/net/tg3.c b/xen/drivers/net/tg3.c index 3e50ba408b..144d89ceb9 100644 --- a/xen/drivers/net/tg3.c +++ b/xen/drivers/net/tg3.c @@ -1,4 +1,4 @@ -/* $Id: tg3.c,v 1.43.2.80 2002/03/14 00:10:04 davem Exp $ +/* * tg3.c: Broadcom Tigon3 ethernet driver. * * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) @@ -9,9 +9,9 @@ #include -//#include +#include #include -//#include +#include #include #include #include @@ -50,8 +50,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.2a" -#define DRV_MODULE_RELDATE "Dec 9, 2002" +#define DRV_MODULE_VERSION "1.4c" +#define DRV_MODULE_RELDATE "Feb 18, 2003" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -137,6 +137,12 @@ static struct pci_device_id tg3_pci_tbl[] __devinitdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, 0x4400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000, @@ -159,6 +165,8 @@ static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) spin_unlock_irqrestore(&tp->indirect_lock, flags); } else { writel(val, tp->regs + off); + if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) + readl(tp->regs + off); } } @@ -204,6 +212,12 @@ static void tg3_disable_ints(struct tg3 *tp) tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); } +static inline void tg3_cond_int(struct tg3 *tp) +{ + if (tp->hw_status->status & SD_STATUS_UPDATED) + tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); +} + static void tg3_enable_ints(struct tg3 *tp) { tw32(TG3PCI_MISC_HOST_CTRL, @@ -211,9 +225,61 @@ static void tg3_enable_ints(struct tg3 *tp) tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); - if (tp->hw_status->status & SD_STATUS_UPDATED) - tw32(GRC_LOCAL_CTRL, - tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); + tg3_cond_int(tp); +} + +#ifdef NAPI +/* these netif_xxx funcs should be moved into generic net layer */ +static void netif_poll_disable(struct net_device *dev) +{ + while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + } +} + +static inline void netif_poll_enable(struct net_device *dev) +{ + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + +/* same as netif_rx_complete, except that local_irq_save(flags) + * has already been issued + */ +static inline void __netif_rx_complete(struct net_device *dev) +{ + if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG(); + list_del(&dev->poll_list); + clear_bit(__LINK_STATE_RX_SCHED, &dev->state); +} +#endif + +static inline void netif_tx_disable(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); + netif_stop_queue(dev); + spin_unlock_bh(&dev->xmit_lock); +} + +static inline void tg3_netif_stop(struct tg3 *tp) +{ +#ifdef NAPI + netif_poll_disable(tp->dev); +#endif + netif_tx_disable(tp->dev); +} + +static inline void tg3_netif_start(struct tg3 *tp) +{ + netif_wake_queue(tp->dev); + /* NOTE: unconditional netif_wake_queue is only appropriate + * so long as all callers are assured to have free tx slots + * (such as after tg3_init_hw) + */ +#ifdef NAPI + netif_poll_enable(tp->dev); +#endif + tg3_cond_int(tp); } static void tg3_switch_clocks(struct tg3 *tp) @@ -375,7 +441,6 @@ static int tg3_phy_reset(struct tg3 *tp, int force) } static int tg3_setup_phy(struct tg3 *); -static int tg3_halt(struct tg3 *); static int tg3_set_power_state(struct tg3 *tp, int state) { @@ -446,8 +511,6 @@ static int tg3_set_power_state(struct tg3 *tp, int state) tg3_setup_phy(tp); } - tg3_halt(tp); - pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { @@ -879,6 +942,20 @@ static int tg3_setup_copper_phy(struct tg3 *tp) tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02); + /* Some third-party PHYs need to be reset on link going + * down. + * + * XXX 5705 note: This workaround also applies to 5705_a0 + */ + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && + netif_carrier_ok(tp->dev)) { + tg3_readphy(tp, MII_BMSR, &bmsr); + tg3_readphy(tp, MII_BMSR, &bmsr); + if (!(bmsr & BMSR_LSTATUS)) + tg3_phy_reset(tp, 1); + } + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1937,13 +2014,12 @@ static int tg3_rx(struct tg3 *tp, int budget) } if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) && - (desc->type_flags & RXD_FLAG_TCPUDP_CSUM)) { - skb->csum = htons((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) - >> RXD_TCPCSUM_SHIFT); - skb->ip_summed = CHECKSUM_HW; - } else { + (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && + (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) + >> RXD_TCPCSUM_SHIFT) == 0xffff)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else skb->ip_summed = CHECKSUM_NONE; - } skb->protocol = eth_type_trans(skb, tp->dev); #if TG3_VLAN_TAG_USED @@ -1953,11 +2029,10 @@ static int tg3_rx(struct tg3 *tp, int budget) desc->err_vlan & RXD_VLAN_MASK); } else #endif - #ifdef NAPI netif_receive_skb(skb); #else - netif_rx(skb); + netif_rx(skb); #endif tp->dev->last_rx = jiffies; received++; @@ -2000,11 +2075,12 @@ static int tg3_poll(struct net_device *netdev, int *budget) { struct tg3 *tp = netdev->priv; struct tg3_hw_status *sblk = tp->hw_status; - int done; -#ifdef NAPI unsigned long flags; + int done; + spin_lock_irqsave(&tp->lock, flags); -#endif + + /* handle link change and other phy events */ if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES))) { @@ -2015,26 +2091,33 @@ static int tg3_poll(struct net_device *netdev, int *budget) } } + /* run TX completion thread */ if (sblk->idx[0].tx_consumer != tp->tx_cons) { spin_lock(&tp->tx_lock); tg3_tx(tp); spin_unlock(&tp->tx_lock); } + spin_unlock_irqrestore(&tp->lock, flags); + + /* run RX thread, within the bounds set by NAPI. + * All RX "locking" is done by ensuring outside + * code synchronizes with dev->poll() + */ done = 1; if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { int work_done; #ifdef NAPI int orig_budget = *budget; + if (orig_budget > netdev->quota) orig_budget = netdev->quota; work_done = tg3_rx(tp, orig_budget); - + *budget -= work_done; netdev->quota -= work_done; - if (work_done >= orig_budget) done = 0; #else @@ -2042,12 +2125,13 @@ static int tg3_poll(struct net_device *netdev, int *budget) #endif } #ifdef NAPI + /* if no more work, tell net stack and NIC we're done */ if (done) { - netif_rx_complete(netdev); + spin_lock_irqsave(&tp->lock, flags); + __netif_rx_complete(netdev); tg3_enable_ints(tp); + spin_unlock_irqrestore(&tp->lock, flags); } - - spin_unlock_irqrestore(&tp->lock, flags); #endif return (done ? 0 : 1); } @@ -2057,12 +2141,14 @@ static inline unsigned int tg3_has_work(struct net_device *dev, struct tg3 *tp) struct tg3_hw_status *sblk = tp->hw_status; unsigned int work_exists = 0; + /* check for phy events */ if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES))) { if (sblk->status & SD_STATUS_LINK_CHG) work_exists = 1; } + /* check for RX/TX work to do */ if (sblk->idx[0].tx_consumer != tp->tx_cons || sblk->idx[0].rx_producer != tp->rx_rcb_ptr) work_exists = 1; @@ -2080,16 +2166,30 @@ static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) unsigned long flags; spin_lock_irqsave(&tp->lock, flags); -#if NAPI +#ifdef NAPI if (sblk->status & SD_STATUS_UPDATED) { + /* + * writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. + */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + /* + * Flush PCI write. This also guarantees that our + * status block has been flushed to host memory. + */ tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); sblk->status &= ~SD_STATUS_UPDATED; if (likely(tg3_has_work(dev, tp))) - netif_rx_schedule(dev); + netif_rx_schedule(dev); /* schedule NAPI poll */ else { + /* no work, shared interrupt perhaps? re-enable + * interrupts, and flush that PCI write + */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); @@ -2097,33 +2197,34 @@ static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) } #else { - int budget = 1000; - tg3_poll( dev, &budget ); + int budget = 1000; + tg3_poll( dev, &budget ); - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); - tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); - - + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); } #endif - spin_unlock_irqrestore(&tp->lock, flags); } static void tg3_init_rings(struct tg3 *); static int tg3_init_hw(struct tg3 *); +static int tg3_halt(struct tg3 *); -static void tg3_tx_timeout(struct net_device *dev) +static void tg3_reset_task(void *_data) { - struct tg3 *tp = dev->priv; + struct tg3 *tp = _data; + unsigned int restart_timer; - printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", - dev->name); + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); + restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; + tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; + tg3_halt(tp); tg3_init_rings(tp); tg3_init_hw(tp); @@ -2131,7 +2232,30 @@ static void tg3_tx_timeout(struct net_device *dev) spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - netif_wake_queue(dev); + tg3_netif_start(tp); + + if (restart_timer) + mod_timer(&tp->timer, jiffies + 1); +} + +static void tg3_tx_timeout(struct net_device *dev) +{ + struct tg3 *tp = dev->priv; + + printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", + dev->name); + + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + + tg3_halt(tp); + tg3_init_rings(tp); + tg3_init_hw(tp); + + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + + netif_wake_queue(dev); } #if !PCI_DMA_BUS_IS_PHYS @@ -2206,11 +2330,6 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, return -1; } - /* NOTE: Broadcom's driver botches this case up really bad. - * This is especially true if any of the frag pages - * are in highmem. It will instantly oops in that case. - */ - /* New SKB is guarenteed to be linear. */ entry = *start; new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len, @@ -2642,6 +2761,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) return 0; } + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -2654,6 +2774,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); return 0; } @@ -3029,6 +3150,7 @@ out: static void tg3_chip_reset(struct tg3 *tp) { u32 val; + u32 flags_save; /* Force NVRAM to settle. * This deals with a chip bug which can result in EEPROM @@ -3045,8 +3167,21 @@ static void tg3_chip_reset(struct tg3 *tp) } } + /* + * We must avoid the readl() that normally takes place. + * It locks machines, causes machine checks, and other + * fun things. So, temporarily disable the 5701 + * hardware workaround, while we do the reset. + */ + flags_save = tp->tg3_flags; + tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; + + /* do the reset */ tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET); + /* restore 5701 hardware bug workaround flag */ + tp->tg3_flags = flags_save; + /* Flush PCI posted writes. The normal MMIO registers * are inaccessible at this time so this is the only * way to make this reliably. I tried to use indirect @@ -4120,18 +4255,29 @@ static int tg3_reset_hw(struct tg3 *tp) udelay(10); } - // akw: I have set these all back to default coalescing values. - - tw32(HOSTCC_RXCOL_TICKS, DEFAULT_RXCOL_TICKS); //0); - tw32(HOSTCC_RXMAX_FRAMES, DEFAULT_RXMAX_FRAMES); //1); - tw32(HOSTCC_RXCOAL_TICK_INT, DEFAULT_RXCOAL_TICK_INT); //, 0); - tw32(HOSTCC_RXCOAL_MAXF_INT, DEFAULT_RXCOAL_MAXF_INT); //, 1); - tw32(HOSTCC_TXCOL_TICKS, DEFAULT_TXCOL_TICKS); //, LOW_TXCOL_TICKS); - tw32(HOSTCC_TXMAX_FRAMES, DEFAULT_TXMAX_FRAMES); //, LOW_RXMAX_FRAMES); - tw32(HOSTCC_TXCOAL_TICK_INT, DEFAULT_TXCOAL_TICK_INT); //, 0); - tw32(HOSTCC_TXCOAL_MAXF_INT, DEFAULT_TXCOAL_MAXF_INT); //, 0); +#ifdef NAPI + tw32(HOSTCC_RXCOL_TICKS, 0); + tw32(HOSTCC_RXMAX_FRAMES, 1); + tw32(HOSTCC_RXCOAL_TICK_INT, 0); + tw32(HOSTCC_RXCOAL_MAXF_INT, 1); + tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS); + tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES); + tw32(HOSTCC_TXCOAL_TICK_INT, 0); + tw32(HOSTCC_TXCOAL_MAXF_INT, 0); tw32(HOSTCC_STAT_COAL_TICKS, DEFAULT_STAT_COAL_TICKS); +#else + tw32(HOSTCC_RXCOL_TICKS, DEFAULT_RXCOL_TICKS); + tw32(HOSTCC_RXMAX_FRAMES, DEFAULT_RXMAX_FRAMES); + tw32(HOSTCC_RXCOAL_TICK_INT, DEFAULT_RXCOAL_TICK_INT); + tw32(HOSTCC_RXCOAL_MAXF_INT, DEFAULT_RXCOAL_MAXF_INT); + tw32(HOSTCC_TXCOL_TICKS, DEFAULT_TXCOL_TICKS); + tw32(HOSTCC_TXMAX_FRAMES, DEFAULT_TXMAX_FRAMES); + tw32(HOSTCC_TXCOAL_TICK_INT, DEFAULT_TXCOAL_TICK_INT); + tw32(HOSTCC_TXCOAL_MAXF_INT, DEFAULT_TXCOAL_MAXF_INT); + tw32(HOSTCC_STAT_COAL_TICKS, + DEFAULT_STAT_COAL_TICKS); +#endif /* Status/statistics block address. */ tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, @@ -4258,6 +4404,12 @@ static int tg3_reset_hw(struct tg3 *tp) if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) tw32(MAC_SERDES_CFG, 0x616000); + /* Prevent chip from dropping frames when flow control + * is enabled. + */ + tw32(MAC_LOW_WMARK_MAX_RX_FRAME, 2); + tr32(MAC_LOW_WMARK_MAX_RX_FRAME); + err = tg3_setup_phy(tp); if (err) return err; @@ -4344,9 +4496,17 @@ static void tg3_timer(unsigned long __opaque) } if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - tg3_halt(tp); - tg3_init_rings(tp); - tg3_init_hw(tp); + tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; + spin_unlock(&tp->tx_lock); + spin_unlock_irqrestore(&tp->lock, flags); +#if 0 + schedule_task(&tp->reset_task); +#else + tg3_halt(tp); + tg3_init_rings(tp); + tg3_init_hw(tp); +#endif + return; } /* This part only runs once per second. */ @@ -4477,8 +4637,6 @@ static int tg3_open(struct net_device *dev) return err; } - netif_start_queue(dev); - spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -4487,6 +4645,8 @@ static int tg3_open(struct net_device *dev) spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + netif_start_queue(dev); + return 0; } @@ -5252,6 +5412,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) (ering.tx_pending > TG3_TX_RING_SIZE - 1)) return -EINVAL; + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -5265,6 +5426,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) netif_wake_queue(tp->dev); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); return 0; } @@ -5287,6 +5449,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) if (copy_from_user(&epause, useraddr, sizeof(epause))) return -EFAULT; + tg3_netif_stop(tp); spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); if (epause.autoneg) @@ -5306,6 +5469,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) tg3_init_hw(tp); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); return 0; } @@ -5974,6 +6138,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); } } + + /* Back to back register writes can cause problems on this chip, + * the workaround is to read back all reg writes except those to + * mailbox regs. See tg3_write_indirect_reg32(). + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) + tp->tg3_flags |= TG3_FLAG_5701_REG_WRITE_BUG; + if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0) tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED; if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0) @@ -6000,18 +6172,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; - /* Regardless of whether checksums work or not, we configure - * the StrongARM chips to not compute the pseudo header checksums - * in either direction. Because of the way Linux checksum support - * works we do not need the chips to do this, and taking the load - * off of the TX/RX onboard StrongARM cpus means that they will not be - * the bottleneck. Whoever wrote Broadcom's driver did not - * understand the situation at all. He could have bothered - * to read Jes's Acenic driver because the logic (and this part of - * the Tigon2 hardware/firmware) is pretty much identical. + /* Pseudo-header checksum is done by hardware logic and not + * the offload processers, so make the chip do the pseudo- + * header checksums on receive. For transmit it is more + * convenient to do the pseudo-header checksum in software + * as Linux does that on transmit for us in all cases. */ tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM; - tp->tg3_flags |= TG3_FLAG_NO_RX_PSEUDO_CSUM; + tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM; /* Derive initial jumbo mode from MTU assigned in * ether_setup() via the alloc_etherdev() call @@ -6089,24 +6257,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) tp->tg3_flags |= TG3_FLAG_HOST_TXDS; - /* Quick sanity check. Make sure we see an expected - * value here. - */ grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; - if (grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5700 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5701 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5702FE && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703S && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704_A2 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704_X && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_AC91002A1) { - printk(KERN_ERR PFX "(%s) unknown board id 0x%08X\n", - tp->pdev->slot_name, grc_misc_cfg); - return -ENODEV; - } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { @@ -6114,10 +6266,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; } - /* ROFL, you should see Broadcom's driver code implementing - * this, stuff like "if (a || b)" where a and b are always - * mutually exclusive. DaveM finds like 6 bugs today, hello! - */ + /* this one is limited to 10/100 only */ if (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5702FE) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; @@ -6180,24 +6329,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* 5700 chips can get confused if TX buffers straddle the * 4GB address boundary in some cases. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) { - /* ROFL! Latest Broadcom driver disables NETIF_F_HIGHDMA - * in this case instead of fixing their workaround code. - * - * Like, hey, there is this skb_copy() thing guys, - * use it. Oh I can't stop laughing... - */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) tp->dev->hard_start_xmit = tg3_start_xmit_4gbug; - } else { + else tp->dev->hard_start_xmit = tg3_start_xmit; - } tp->rx_offset = 2; - +/* XXX Xen: we trust our ASICs, for better or worse ;-) */ +#if 0 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) - printk("WARNING: This card may not support unaligned receive pointers.\n"); - //tp->rx_offset = 0; + tp->rx_offset = 0; +#endif /* By default, disable wake-on-lan. User can change this * using ETHTOOL_SWOL. @@ -6358,6 +6501,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) (0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) | (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) | (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT); + /* XXX 5705 note: set MIN_DMA to zero here */ } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) tp->dma_rwctrl = @@ -6375,13 +6519,20 @@ static int __devinit tg3_test_dma(struct tg3 *tp) (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT); /* Wheee, some more chip bugs... */ - if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 || - tp->pci_chip_rev_id == CHIPREV_ID_5703_A2 || - tp->pci_chip_rev_id == CHIPREV_ID_5703_A3 || - tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) - tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); + + if (ccval == 0x6 || ccval == 0x7) + tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; + } } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) + tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA + << DMA_RWCTRL_MIN_DMA_SHIFT); + /* We don't do this on x86 because it seems to hurt performace. * It does help things on other platforms though. */ @@ -6445,8 +6596,11 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } #endif - /* Remove this if it causes problems for some boards. */ - tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { + /* Remove this if it causes problems for some boards. */ + tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT; + } tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); @@ -6676,6 +6830,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, spin_lock_init(&tp->lock); spin_lock_init(&tp->tx_lock); spin_lock_init(&tp->indirect_lock); + PREPARE_TQUEUE(&tp->reset_task, tg3_reset_task, tp); tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len); if (tp->regs == 0UL) { @@ -6808,6 +6963,8 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state) if (!netif_running(dev)) return 0; + tg3_netif_stop(tp); + spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); tg3_disable_ints(tp); @@ -6834,6 +6991,7 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state) spin_unlock_irq(&tp->lock); netif_device_attach(dev); + tg3_netif_start(tp); } return err; @@ -6864,6 +7022,8 @@ static int tg3_resume(struct pci_dev *pdev) spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); + tg3_netif_start(tp); + return 0; } diff --git a/xen/drivers/net/tg3.h b/xen/drivers/net/tg3.h index d816322d98..dced74af3f 100644 --- a/xen/drivers/net/tg3.h +++ b/xen/drivers/net/tg3.h @@ -21,7 +21,8 @@ #define TG3_BDINFO_NIC_ADDR 0xcUL /* 32-bit */ #define TG3_BDINFO_SIZE 0x10UL -#define RX_COPY_THRESHOLD 0 //256 +/* XXX Xen: No copy break. */ +#define RX_COPY_THRESHOLD 0 /*256*/ #define RX_STD_MAX_SIZE 1536 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ @@ -456,6 +457,7 @@ #define RCV_RULE_DISABLE_MASK 0x7fffffff #define MAC_RCV_RULE_CFG 0x00000500 #define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008 +#define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504 /* 0x504 --> 0x590 unused */ #define MAC_SERDES_CFG 0x00000590 #define MAC_SERDES_STAT 0x00000594 @@ -1139,7 +1141,6 @@ #define GRC_MISC_CFG_BOARD_ID_5704 0x00000000 #define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000 #define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000 -#define GRC_MISC_CFG_BOARD_ID_5704_X 0x0000C000 #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 #define GRC_LOCAL_CTRL 0x00006808 #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 @@ -1795,6 +1796,7 @@ struct tg3 { #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 +#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 @@ -1820,6 +1822,8 @@ struct tg3 { #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 #define TG3_FLAG_SPLIT_MODE 0x40000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000 + u32 tg3_flags2; +#define TG3_FLG2_RESTART_TIMER 0x00000001 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -1888,6 +1892,7 @@ struct tg3 { struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; + struct tq_struct reset_task; }; #endif /* !(_T3_H) */ diff --git a/xen/drivers/pci/pci.ids b/xen/drivers/pci/pci.ids index c4e4283cc5..845f545bf2 100644 --- a/xen/drivers/pci/pci.ids +++ b/xen/drivers/pci/pci.ids @@ -3062,15 +3062,25 @@ 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64) 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS) 4200 Token Ring adapter - 4300 Gigabit Ethernet - 1148 9821 SK-9821 (1000Base-T single link) - 1148 9822 SK-9822 (1000Base-T dual link) - 1148 9841 SK-9841 (1000Base-LX single link) - 1148 9842 SK-9842 (1000Base-LX dual link) - 1148 9843 SK-9843 (1000Base-SX single link) - 1148 9844 SK-9844 (1000Base-SX dual link) - 1148 9861 SK-9861 (1000Base-SX VF45 single link) - 1148 9862 SK-9862 (1000Base-SX VF45 dual link) + 4300 SK-98xx Gigabit Ethernet Server Adapter + 1148 9821 SK-9821 Gigabit Ethernet 1000Base-T Server Adapter + 1148 9822 SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter + 1148 9841 SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter + 1148 9842 SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter + 1148 9843 SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter + 1148 9844 SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter + 1148 9861 SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter + 1148 9862 SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter + 1148 9871 SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter + 1148 9872 SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter + 4320 SK-98xx Gigabit Ethernet Server Adapter + 1148 9521 SK-9521 10/100/1000Base-T Adapter + 1148 5021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter + 1148 5041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter + 1148 5043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter + 1148 5051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter + 1148 5061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter + 1148 5071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter 4400 Gigabit Ethernet 1149 Win System Corporation 114a VMIC @@ -5078,6 +5088,9 @@ 164d NetXtreme BCM5702FE Gigabit Ethernet 16a6 NetXtreme BCM5702X Gigabit Ethernet 16a7 NetXtreme BCM5703X Gigabit Ethernet + 16a8 NetXtreme BCM5704S Gigabit Ethernet + 16c6 NetXtreme BCM5702A3 Gigabit Ethernet + 16c7 NetXtreme BCM5703A3 Gigabit Ethernet 4212 BCM v.90 56k modem 5820 BCM5820 Crypto Accelerator 5821 BCM5821 Crypto Accelerator diff --git a/xen/include/xeno/pci_ids.h b/xen/include/xeno/pci_ids.h index 3220beb90c..592abae447 100644 --- a/xen/include/xeno/pci_ids.h +++ b/xen/include/xeno/pci_ids.h @@ -412,6 +412,7 @@ #define PCI_DEVICE_ID_AMD_8111_LAN 0x7462 #define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 #define PCI_DEVICE_ID_AMD_8111_AC97 0x746d +#define PCI_DEVICE_ID_AMD_8131_APIC 0x7450 #define PCI_VENDOR_ID_TRIDENT 0x1023 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 @@ -830,6 +831,14 @@ #define PCI_DEVICE_ID_3COM_3C905TX 0x9050 #define PCI_DEVICE_ID_3COM_3C905T4 0x9051 #define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055 +#define PCI_DEVICE_ID_3COM_3CR990 0x9900 +#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902 +#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903 +#define PCI_DEVICE_ID_3COM_3CR990B 0x9904 +#define PCI_DEVICE_ID_3COM_3CR990_FX 0x9905 +#define PCI_DEVICE_ID_3COM_3CR990SVR95 0x9908 +#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909 +#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a #define PCI_VENDOR_ID_SMC 0x10b8 #define PCI_DEVICE_ID_SMC_EPIC100 0x0005 @@ -1118,6 +1127,7 @@ #define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000 #define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 #define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 +#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320 #define PCI_VENDOR_ID_VMIC 0x114a #define PCI_DEVICE_ID_VMIC_VME 0x7587 @@ -1580,6 +1590,9 @@ #define PCI_DEVICE_ID_TIGON3_5702FE 0x164d #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 +#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 +#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6 +#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7 #define PCI_VENDOR_ID_SYBA 0x1592 #define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 @@ -1771,6 +1784,7 @@ #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 #define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca +#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb #define PCI_VENDOR_ID_COMPUTONE 0x8e0e #define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 -- 2.30.2